package com.cmuis.goodguide;

import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.text.util.Linkify;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * This Activity / Page is intended for the in-depth information and ratings
 * for a user-selected product. When a user finds the product in the search
 * results, upon clicking the product they are redirected here.
 * @author - Stephanie
 */
public class DetailsPage extends Activity {

	/**
	 * DetailsPage receives a product ID or UPC from the resultspage and
	 * displays the image, product name, and ratings by searching for the
	 * information from the goodguide database. 
	 * (non-Javadoc)
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.details);
		// gets the extra information attached to the intent. In this case, a
		// products ID and UPC.
		Bundle b = this.getIntent().getExtras();
		String prodId = b.getString("productID");
		String prodUpc = b.getString("productUPC");

		// the views that allow for information to be displayed in the
		// application
		final TextView text = (TextView) findViewById(R.id.item_name);
		final ImageView overall_rating = (ImageView) findViewById(R.id.overall_rating);
		final TextView overall_rating_value = (TextView) findViewById(R.id.overall_rating_value);
		final ImageView social_rating = (ImageView) findViewById(R.id.social_rating_img);
		final TextView social_rating_value = (TextView) findViewById(R.id.social_rating_value);
		final ImageView env_rating = (ImageView) findViewById(R.id.env_rating_img);
		final TextView env_rating_value = (TextView) findViewById(R.id.env_rating_value);
		final ImageView health_rating = (ImageView) findViewById(R.id.health_rating_img);
		final TextView health_rating_value = (TextView) findViewById(R.id.health_rating_value);
		final TextView company_name = (TextView) findViewById(R.id.company_name);
		final TextView category_name = (TextView) findViewById(R.id.category_name);
		final TextView brand_name = (TextView) findViewById(R.id.brand_name);
		final TextView product_url = (TextView) findViewById(R.id.product_url);

		// searches the goodguide database for a productId (or product UPC) and
		// returns a product with that id or upc
		final Product item;
		if (prodId != null)
			item = this.openConnection(prodId);
		else
			item = this.openConnectionUpc(prodUpc);

		// if the product is not null, it will set the image of the product
		// taken from the goodguide database
		if (item != null && item.getName() != null) {
			try {
				ImageView i = (ImageView) findViewById(R.id.imview);
				BufferedInputStream buf = new BufferedInputStream(
						(InputStream) new URL(item.getImage()).getContent());
				// gets the image from a url
				Bitmap bitmap = BitmapFactory.decodeStream(buf);
				// sets the products image to the ImageView
				i.setImageBitmap(bitmap);
				buf.close();
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			// sets the products name to the TextView
			text.setText(item.getName().toString());

			// keys in the ratings HashMap are root, social, and environmental.
			// root refers to the overall rating of the product.
			HashMap<String, String> ratings = item.getRatingMap();
			System.out.println(ratings.toString());
			// displays the overall, social, and environmental ratings by
			// setting them to TextViews.
			overall_rating_value.setText(ratings.get("root"));
			social_rating_value.setText(ratings.get("social"));
			env_rating_value.setText(ratings.get("environmental"));

			// sets the background to be displayed depending on the rating
			if (ratings.get("root") != null) {
				if (ratings.get("root").startsWith("-") == false) {
					Double rating = Double.parseDouble(ratings.get("root"));
					if (rating < 2) {
						overall_rating
								.setImageResource(R.drawable.lowest_rating);
					}
					if (rating >= 2 && rating < 4) {
						overall_rating.setImageResource(R.drawable.low_rating);
					}
					if (rating >= 4 && rating < 6) {
						overall_rating.setImageResource(R.drawable.mid_rating);
					}
					if (rating >= 6 && rating < 8) {
						overall_rating
								.setImageResource(R.drawable.mid_high_rating);
					}
					if (rating >= 8 && rating <= 10) {
						overall_rating.setImageResource(R.drawable.high_rating);
					}
				} else {
					health_rating_value.setText("-");
				}
			}
			if (ratings.get("social") != null) {
				if (ratings.get("social").startsWith("-") == false) {
					Double rating = Double.parseDouble(ratings.get("social"));
					if (rating < 2) {
						social_rating
								.setImageResource(R.drawable.lowest_rating);
					}
					if (rating >= 2 && rating < 4) {
						social_rating.setImageResource(R.drawable.low_rating);
					}
					if (rating >= 4 && rating < 6) {
						social_rating.setImageResource(R.drawable.mid_rating);
					}
					if (rating >= 6 && rating < 8) {
						social_rating
								.setImageResource(R.drawable.mid_high_rating);
					}
					if (rating >= 8 && rating <= 10) {
						social_rating.setImageResource(R.drawable.high_rating);
					}
				} else {
					health_rating_value.setText("-");
				}
			}
			if (ratings.get("environmental") != null) {
				if (ratings.get("environmental").startsWith("-") == false) {
					Double rating = Double.parseDouble(ratings
							.get("environmental"));
					if (rating < 2) {
						env_rating.setImageResource(R.drawable.lowest_rating);
					}
					if (rating >= 2 && rating < 4) {
						env_rating.setImageResource(R.drawable.low_rating);
					}
					if (rating >= 4 && rating < 6) {
						env_rating.setImageResource(R.drawable.mid_rating);
					}
					if (rating >= 6 && rating < 8) {
						env_rating.setImageResource(R.drawable.mid_high_rating);
					}
					if (rating >= 8 && rating <= 10) {
						env_rating.setImageResource(R.drawable.high_rating);
					}
				} else {
					health_rating_value.setText("-");
				}
			}
			if (ratings.get("health-and-safety") != null) {
				health_rating_value.setText(ratings.get("health-and-safety"));
				if (ratings.get("health-and-safety").startsWith("-") == false) {
					Double rating = Double.parseDouble(ratings
							.get("health-and-safety"));
					if (rating < 2) {
						health_rating
								.setImageResource(R.drawable.lowest_rating);
					}
					if (rating >= 2 && rating < 4) {
						health_rating.setImageResource(R.drawable.low_rating);
					}
					if (rating >= 4 && rating < 6) {
						health_rating.setImageResource(R.drawable.mid_rating);
					}
					if (rating >= 6 && rating < 8) {
						health_rating
								.setImageResource(R.drawable.mid_high_rating);
					}
					if (rating >= 8 && rating <= 10) {
						health_rating.setImageResource(R.drawable.high_rating);
					}
				}
			} else {
				health_rating_value.setText("-");
			}
			// set the details for the page
			String brand = item.getBrandName();
			String company = item.getCompanyName();
			String category = item.getCategoryName();
			brand_name.setText("Brand: " + brand);
			company_name.setText("Company: " + company);
			category_name.setText("Category: " + category);
			String url = item.getURL();

			//text displayed
			String txt = "View more information on the website";
			product_url.setText(txt);
			// pattern: pattern we want to match and turn into a clickable link
			Pattern pattern = Pattern
					.compile("View more information on the website");
			//Turn it into a link
			Linkify.addLinks(product_url, pattern, url);
			
			//Add product to the history: name and ID
			SharedPreferences prefs = this.getSharedPreferences("prefs",
					MODE_WORLD_READABLE);
			SharedPreferences.Editor editor = prefs.edit();
			editor.putString(item.getName(), item.getId());
			editor.commit();

		} else {
			text.setText("The UPC for this item is not in the database :(");
		}
	}

	/**
	 * Talks with the Goodguide API to get XML information on a product, then parses the
	 * info into a Product Object.
	 */
	protected Product openConnectionUpc(String upc) {

		try {
			URL url = new URL(
					"http://api.goodguide.com/"
							+ "search.xml?api_key=chm22jq6d5f5ytnnnfwan726&api_version=1.0&"
							+ "api_format=simple&upc=" + upc);

			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();

			XMLReader xr = sp.getXMLReader();

			ProductParser handler = new ProductParser();
			xr.setContentHandler(handler);

			xr.parse(new InputSource(url.openStream()));
			if (handler.getProduct() != null)
				return handler.getProduct();
			else
				return null;

		} catch (Exception e) {
			return null;
		}

	}
	
	/**
	 * Talks with the Goodguide API to get XML information from a given product id, then returns the parsed
	 * information as a Product object (makes it a user friendly format)
	 */
	protected Product openConnection(String id) {
		try {
			URL url = new URL(
					"http://api.goodguide.com/"
							+ "search.xml?api_key=chm22jq6d5f5ytnnnfwan726&api_version=1.0&"
							+ "api_format=simple&id=" + id);

			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();

			XMLReader xr = sp.getXMLReader();

			ProductParser handler = new ProductParser();
			xr.setContentHandler(handler);

			xr.parse(new InputSource(url.openStream()));

			return handler.getProduct();

		} catch (Exception e) {
			return null;
		}

	}
	
	/**
	 * Creates the standard menu in android applications.
	 * (non-Javadoc)
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 */
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.options_menu, menu);
		return true;
	}

	/**
	 * Sets the menu options in the standard android menu for each main activity in the
	 * application.
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		case R.id.search:
			Intent i = new Intent(this, goodguide.class);
			startActivity(i);
			return true;
		case R.id.barcode_scanner:
			Intent j = new Intent(this, barcodescanner.class);
			startActivity(j);
			return true;
		case R.id.history:
			Intent p = new Intent(this, History.class);
			startActivity(p);
			return true;
		case R.id.info:
			Intent q = new Intent(this, InfoPage.class);
			startActivity(q);
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}
}
